import {
    request,
    AbstractBookCrawler,
    BasicBook,
    SearchBookResult,
    Book,
    BasicChapter,
    BookCrawlerTest,
    BookSource,
    removeQuerySelector,
    getPathFromUrl
} from "../../common/common_node.js";

class BookCrawler extends AbstractBookCrawler {

    options = {
        proxy: "http://127.0.0.1:10809"
    }

    async searchBook(keyword, pageNum) {
        function getBoolList($) {
            const bookArr = [];
            const liArr = $("ul.library li");
            liArr.each(function (index, elem) {
                let nameAndPath = $(this).find("a.bookname");
                bookArr.push(new BasicBook({
                    name: nameAndPath.text(),
                    author: $(this).find('.author').text(),
                    path: getPathFromUrl(nameAndPath.attr("href")),
                }));
            })
            return bookArr;
        }

        let url = `${this.source.searchBaseUrl}/search?keyword=${keyword}&page=${pageNum}`;
        const response = await request(url, {
            method: 'POST',
            ...this.options
        });

        console.log("response", response);

        const doc = await (response).doc();
        const bookArr = getBoolList(doc);

        let pages = 1;
        const btnArr = doc(".page .a-btn");
        if (btnArr && btnArr.length > 0) {
            const pageUrl = btnArr.last().attr("href");
            const regex = /searchpost\(.+?,(\d+),/;
            const matches = pageUrl.match(regex);
            pages = matches ? parseInt(matches[1]) : null;
        }
        return new SearchBookResult({
            pageNum: pageNum,
            pages: pages,
            keyword: keyword,
            bookList: bookArr
        });
    }

    async bookDetails(path) {
        const $ = await (await request(this.source.bookBaseUrl + path, this.options)).doc();
        return new Book({
            name: $("meta[property='og:novel:book_name']").attr('content'),
            author: $("meta[property='og:novel:author']").attr('content'),
            path: path,
            intro: $(".intro").text(),
            coverUrl: $(".bookimg img").attr('src'),
            type: $("meta[property='og:novel:category']").attr('content'),
        });
    }

    async bookCatalog(path) {
        const $ = await (await request(this.source.bookBaseUrl + path + 'chapterlist', this.options)).doc();
        const chapters = $('.read dl:eq(1) dd a');
        let catalog = [];
        chapters.each(function (i, elem) {
            const item = $(elem);
            catalog.push(new BasicChapter({
                index: i,
                title: item.text().trim().replace("\n", ""),
                path: getPathFromUrl(item.attr("href"))
            }));
        });
        return catalog;
    }

    async chapterContent(path) {
        const $ = await (await request(this.source.bookBaseUrl + path, this.options)).doc();
        // let content = $("#content").html().replace(/\([^)]*\)•\([^)]*\)/g, '');

        let content = '';
        const pTags = removeQuerySelector($('#content'), 'a').find('p');
        pTags.each(function (index) {
            content += $(this).text();
            // 如果不是最后一个p标签，则添加换行符
            if (index !== pTags.length - 1) {
                content += '\n';
            }
        });

        let next = $("#page2")
        if (next.text().includes("下一页")) {
            content += '\n' + await this.chapterContent(path.replace(/\/[^/]+\.html$/, '/') + next.attr("href"));
        }
        return content;
    }
}

const source = {
    "id": "free_book_js/9",
    "name": "格格党",
    "portalUrl": "http://www.ggdwx.net",
    "searchBaseUrl": "http://www.ggdwx.net",
    "bookBaseUrl": "http://www.ggdwx.net",
    "active": true
};

await new BookCrawlerTest(new BookCrawler(BookSource.createTestBookSource(source)), {
    enableSearch: true,
    keyword: "重生",
}).run();